package br.com.unirio.formula1.servico;

import java.util.HashMap;
import java.util.Map;

import br.com.unirio.formula1.modelo.Corrida;
import br.com.unirio.formula1.modelo.Piloto;
import br.com.unirio.formula1.modelo.Resultado;

/**
 * Classe que representa um colocado de uma Classificacao Geral de Pilotos ({@link ClassificacaoPiloto}).
 * E composta pela posicao do colocado, o piloto representado, seu total de pontos e dois mapeamentos :
 * 
 * historicoDePosicoesDoPiloto - Mapeia a quantidade de vezes que um piloto obteve uma determinada posicao
 * <Posicao,Quantidade>
 * Este mapeamento e necessario para a aplicacao de criterios de desempate entre colocados.
 * 
 * historicoDePontosEmCorridasDoPiloto - Mapeia os pontos que o colocado obteve em determinada corrida <Corrida,Pontos>
 * Este mapeamento e necessario para a exibicao dos pontos por corrida do colocado. Fatalmente a soma de todos os values
 * desse mapeamento deve ser igual ao total de pontos do colocado.
 * 
 * 
 * @author Victor
 * 
 */
public class ColocacaoPiloto implements Comparable<ColocacaoPiloto>
{

    private int posicao;
    private Piloto piloto;
    private double totalPontos;
    private Map<Integer, Integer> historicoDePosicoesDoPiloto;
    private Map<Corrida, Double> historicoDePontosEmCorridasDoPiloto;

    public ColocacaoPiloto(Piloto piloto, int quantidadePilotos)
    {

	this.piloto = piloto;
	historicoDePosicoesDoPiloto = new HashMap<Integer, Integer>();
	historicoDePontosEmCorridasDoPiloto = new HashMap<Corrida, Double>();
	this.posicao = 0;
	totalPontos = 0;

	// inicializacao com pontuacao zero em todas as posicoes possiveis que um piloto possa ter
	for (int i = 1; i <= quantidadePilotos; i++)
	{
	    historicoDePosicoesDoPiloto.put(i, 0);
	}

    }

    public double getPontosEmCorrida(Corrida c)
    {
	Double pontos = historicoDePontosEmCorridasDoPiloto.get(c);
	if (pontos == null)
	    return 0;
	else
	    return pontos;

    }

    public double getPontosEmCorrida(int idCorrida)
    {
	Corrida c = getCorrida(idCorrida);
	Double pontos = historicoDePontosEmCorridasDoPiloto.get(c);
	if (pontos == null)
	    return 0;
	else
	    return pontos;

    }

    public double getPontosEmCorrida(String nomeCorrida)
    {
	Corrida c = getCorrida(nomeCorrida);
	Double pontos = historicoDePontosEmCorridasDoPiloto.get(c);
	if (pontos == null)
	    return 0;
	else
	    return pontos;

    }

    private Corrida getCorrida(String nome)
    {
	for (Corrida corrida : historicoDePontosEmCorridasDoPiloto.keySet())
	{
	    if (corrida.getNome().equals(nome))
		return corrida;
	}
	return null;
    }

    private Corrida getCorrida(int idCorrida)
    {
	for (Corrida corrida : historicoDePontosEmCorridasDoPiloto.keySet())
	{
	    if (corrida.getId() == idCorrida)
		return corrida;
	}
	return null;
    }

    public int getPosicao()
    {
	return posicao;
    }

    public void setPosicao(int posicao)
    {
	this.posicao = posicao;
    }

    public Map<Corrida, Double> getPontosCorridas()
    {
	return historicoDePontosEmCorridasDoPiloto;
    }

    public void setPontosCorridas(Map<Corrida, Double> pontosCorridas)
    {
	this.historicoDePontosEmCorridasDoPiloto = pontosCorridas;
    }

    public Map<Integer, Integer> getHistoricoPosicoesPiloto()
    {
	return historicoDePosicoesDoPiloto;
    }

    public void setHistoricoPosicoesPiloto(Map<Integer, Integer> historicoPosicoesPiloto)
    {
	this.historicoDePosicoesDoPiloto = historicoPosicoesPiloto;
    }

    public double getTotalPontos()
    {
	return totalPontos;
    }

    public void setTotalPontos(double pontos)
    {
	this.totalPontos = pontos;
    }

    public int getQuantidadePosicao(int i)
    {
	return historicoDePosicoesDoPiloto.get(i);
    }

    public Piloto getPiloto()
    {
	return piloto;
    }

    public void setPiloto(Piloto piloto)
    {
	this.piloto = piloto;
    }

    public void addResultado(Resultado resultado)
    {
	double pontosDoPiloto = resultado.getPontos(piloto);
	totalPontos += pontosDoPiloto;
	historicoDePontosEmCorridasDoPiloto.put(resultado.getCorrida(), pontosDoPiloto);

	// incremento no historico de posicoes do piloto com a posicao que o piloto conseguiu no dado resultado

	int posicaoPiloto = resultado.getPosicaoPiloto(piloto);

	// se o piloto participou/finalizou a corrida
	if (posicaoPiloto != 0)
	{
	    Integer numeroPosicoesAnterior = historicoDePosicoesDoPiloto.get(posicaoPiloto);
	    if (numeroPosicoesAnterior != null)
		historicoDePosicoesDoPiloto.put(posicaoPiloto, ++numeroPosicoesAnterior);
	}

    }

    @Override
    public int compareTo(ColocacaoPiloto o)
    {
	if (o.getPosicao() == this.posicao)
	    return 0;
	if (o.getPosicao() > this.posicao)
	    return -1;
	return 1;
    }

}